package nl.mkmedia.tuio {
	import nl.mkmedia.tuio.behaviours.IBehaviour;
	import flash.display.DisplayObject;
	import flash.display.Stage;

	/**
	 * @author Mingoes Kukupessy (mingoes at gmail dot com)
	 */
	public class TUIO {

		private var _tuioSocket : TUIOSocket;
		private var _stage : Stage;
		private var _registeredObjects : Array = new Array();
		private var _tuioPoints : Array = new Array();

		public function TUIO(stage : Stage)
		{
			_stage = stage;
			_tuioSocket = new TUIOSocket('127.0.0.1', 3000, setAlive, setSet);
		}

		public function register(object : DisplayObject, behaviours : Array) : void
		{
			var behaviourInstances : Array = new Array();
			for each (var behaviour : Class in behaviours) {
				behaviourInstances.push(new behaviour(object));
			}
			_registeredObjects.push([object, behaviourInstances]);
		}

		public function setAlive(idArray : Array = null) : void
		{ 
			setAllDead();
			for each (var id : int in idArray) {
				if(id == 0) break;
				var point : TUIOPoint = getPointById(id);
				if(!point) { 
					point = new TUIOPoint(id, 0, 0); 
					_tuioPoints.push(point);
				}
				point.alive = true;
			}
			removeDeads();
		}

		public function setSet(id : int, x : Number, y : Number) : void
		{
			var point : TUIOPoint = getPointById(id);
			if(!point) return;
			point.oldX = point.x;
			point.oldY = point.y;
			point.x = _stage.stageWidth * x;
			point.y = _stage.stageHeight * y;
			point.dX = point.x - (point.oldX == 0 ? point.x : point.oldX);
			point.dY = point.y - (point.oldY == 0 ? point.y : point.oldY);
			callBehaviours();
		}
		
		private function setAllDead() : void
		{
			for each (var point : TUIOPoint in _tuioPoints) point.alive = false;
		}
		
		private function removeDeads() : void
		{
			for each (var point : TUIOPoint in _tuioPoints){
				if(!point.alive) _tuioPoints.splice(_tuioPoints.indexOf(point),1);
			}
		}
		
		private function getPointById(id : int) : TUIOPoint
		{
			for each (var point : TUIOPoint in _tuioPoints) { 
				if(point.id == id) return point;
			}
			return null;
		}
		
		private function callBehaviours() : void
		{
			for each (var registry : Array in _registeredObjects) {
				for each (var behaviour : IBehaviour in registry[1]) {
					behaviour.act(_tuioPoints);
				}
			}
		}

	}
}
